package com.thread.n6;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;

public class TestAccount {
    public static void main(String[] args) {
        Account account=new DecimalAccountCas(new BigDecimal(10000));
        Account.demo(account);
    }
}

class DecimalAccountCas implements Account{
    private AtomicReference<BigDecimal> account;
    public DecimalAccountCas(BigDecimal account) {
        this.account = new AtomicReference<>(account);
    }
    @Override
    public BigDecimal getBalance() {
        return account.get();
    }
    @Override
    public void withdraw(BigDecimal amount) {
        while(true){
            BigDecimal prev=account.get();
            BigDecimal next = prev.subtract(amount);
            if(account.compareAndSet(prev,next)){
                break;
            }
        }
    }
}

//class AccountCas implements Account{
//    private AtomicInteger account;
//    @Override
//    public Integer getBalance() {
//        return account.get();
//    }
//    public AccountCas(int account) {
//        this.account = new AtomicInteger(account);
//    }
//    @Override
//    public void withdraw(Integer amount) {
//        while(true){
//            //获取余额最新值
//            int prev=account.get();
//            //要修改的金额
//            int next=prev-amount;
//            //真正修改
//            if(account.compareAndSet(prev,next)){
//                break;
//            }
//        }
//    }
//}

//class AccountUnsafe implements Account{
//    private Integer account;
//    @Override
//    public synchronized Integer getBalance() {
//        return account;
//    }
//
//    public AccountUnsafe(Integer account) {
//        this.account = account;
//    }
//
//    @Override
//    public synchronized void withdraw(Integer amount) {
//
//        if(this.account>=amount)this.account-=amount;
//        else
//            return;
//    }
//}

interface Account{
    BigDecimal getBalance();
    void withdraw(BigDecimal amount);

   public  static void demo(Account account){
        List<Thread> ts=new ArrayList<>();
        for (int i = 0; i < 1000; i++) {
            ts.add(new Thread(()->{
                account.withdraw(new BigDecimal(10));
            }));
        }
       for (Thread t : ts) {
           t.start();
       }
        for (Thread t : ts) {
            try {
                t.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
       System.out.println(account.getBalance());

    }

}